package com.atguigu.redis_springboot.service;

import com.atguigu.redis_springboot.bean.Employee;
import com.atguigu.redis_springboot.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;

@CacheConfig(cacheNames = "emp") //抽取缓存的公共配置
@Service
public class EmployeeService {

    @Autowired
    EmployeeMapper employeeMapper;

    /**
     * 将方法的运行结果进行缓存：以后再要相同的数据，直接从缓存中获取，不用调用方法；
     *
     * CacheManager管理多个Cache组件，对缓存的真正CRUD操作在Cache组件中，每一个缓存组件有自己唯一的名字；
     * 几个属性：
     *      cacheNames/values:指定缓存组件的名字；将方法的返回结果方法在哪个缓存中，是数组的方式，可以指定多个缓存；
     *      key:缓存组件使用的key；可以使用它来指定。默认是使用方法参数的值。
     *          编写SpEL
     *      keyGenerator:key的生成器:可以自己指定key的生成器;
     *      cacheManager:指定缓存管理器；或者cacheResolver指定缓存解析器;
     *      condition:指定符合条件情况下才缓存；
     *      unless:指定条件为true，方法的返回值就不会缓存；可以获取到结果进行判断；
     *      sync:是否使用异步模式；
     * @param id
     * @return
     */
    @Cacheable(/*cacheNames = "emp",*/key = "#a0"/*,key = "#root.methodName + '[' + #args[0] + ']'",keyGenerator = "keyGenerator",condition = "#root.args[0] > 1"*/)
    public Employee getEmp(Integer id){
        System.out.println("查询" + id + "号员工");
        return employeeMapper.getEmpById(id);
    }

    /**
     * @CachePut：既调用方法，又更新缓存数据；
     * 修改数据库某个数据，同时更新缓存；
     * 运行时机：
     *  1、先调用目标方法
     *  2、将目标方法的结果缓存起来
     *
     * 测试步骤：
     *  1、查询1号员工；查询到的结果会放在缓存中
     *      key:1   value:lastName:zs
     *  2、以后查询还是之前的结果
     *  3、更新1号员工，将方法返回值也放进缓存中
     *      key:传入的Employee对象
     *      value:返回的Employee对象
     *  4、查询1号员工:更新前的数据
     */
    @CachePut(/*value = "emp",*/key = "#result.id")
    public Employee updateEmp(Employee employee){
        System.out.println("updateEmp:" + employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

    /**
     * @CacheEvict:清楚缓存
     * key:指定要清除的数据
     */
    @CacheEvict(/*value = "emp",*/key = "#id")
    public void deleteEmp(Integer id){
        System.out.println("deleteEmp" + id);
        //employeeMapper.deleteEmpById(id);
    }

    /**
     * @CacheEvict:清楚缓存
     * allEntries = true:清除所有（默认false）
     * beforeInvocation = true:缓存的清除是否在方法之前执行（不管方法是否出错，都会清空）（默认false）
     */
    @CacheEvict(/*value = "emp",*/allEntries = true)
    public void deleteAll(){
        System.out.println("deleteAll");
        //employeeMapper.deleteAll();
    }

    //@Caching定义复杂的缓存规则
    @Caching(
        cacheable = {
            @Cacheable(/*value = "emp",*/key = "#lastName")
        }/*,
        put = {
            @CachePut(*//*value = "emp",*//*key = "#result.id"),
            @CachePut(*//*value = "emp",*//*key = "#result.email")
        }*/
    )
    public Employee getEmpByLastName(String lastName){
        return employeeMapper.getEmpByLastName(lastName);
    }
}
